home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / machine / twincobr.c < prev    next >
C/C++ Source or Header  |  2000-04-23  |  11KB  |  321 lines

  1. /****************************************************************************
  2.  *    Twin Cobra                                                                *
  3.  *    Communications and memory functions between shared CPU memory spaces    *
  4.  ****************************************************************************/
  5.  
  6. #include "driver.h"
  7. #include "cpu/tms32010/tms32010.h"
  8.  
  9. #define LOG_DSP_CALLS 0
  10. #define CLEAR 0
  11. #define ASSERT 1
  12.  
  13.  
  14.  
  15. unsigned char *twincobr_68k_dsp_ram;
  16. unsigned char *twincobr_sharedram;
  17. unsigned char *wardner_mainram;
  18.  
  19. extern unsigned char *spriteram;
  20. extern unsigned char *paletteram;
  21.  
  22.  
  23. extern int twincobr_fg_rom_bank;
  24. extern int twincobr_bg_ram_bank;
  25. extern int twincobr_display_on;
  26. extern int twincobr_flip_screen;
  27. extern int twincobr_flip_x_base;
  28. extern int twincobr_flip_y_base;
  29. extern int wardner_sprite_hack;
  30.  
  31. static int coin_count;    /* coin count increments on startup ? , so stop it */
  32. static int dsp_execute;
  33. static unsigned int dsp_addr_w, main_ram_seg;
  34. int toaplan_main_cpu;   /* Main CPU type.  0 = 68000, 1 = Z80 */
  35. #if LOG_DSP_CALLS
  36. static char *toaplan_cpu_type[2] = { "68K" , "Z80" };
  37. #endif
  38.  
  39. int twincobr_intenable;
  40. int fsharkbt_8741;
  41.  
  42.  
  43. void fsharkbt_reset_8741_mcu(void)
  44. {
  45.     /* clean out high score tables in these game hardware */
  46.     int twincobr_cnt;
  47.     int twinc_hisc_addr[12] =
  48.     {
  49.         0x15a4, 0x15a8, 0x170a, 0x170c, /* Twin Cobra */
  50.         0x1282, 0x1284, 0x13ea, 0x13ec, /* Kyukyo Tiger */
  51.         0x016c, 0x0170, 0x02d2, 0x02d4    /* Flying shark */
  52.     };
  53.     for (twincobr_cnt=0; twincobr_cnt < 12; twincobr_cnt++)
  54.     {
  55.         WRITE_WORD(&twincobr_68k_dsp_ram[(twinc_hisc_addr[twincobr_cnt])],0xffff);
  56.     }
  57.  
  58.     toaplan_main_cpu = 0;        /* 68000 */
  59.     twincobr_display_on = 0;
  60.     fsharkbt_8741 = -1;
  61.     twincobr_intenable = 0;
  62.     dsp_addr_w = dsp_execute = 0;
  63.     main_ram_seg = 0;
  64.  
  65.     /* coin count increments on startup ? , so stop it */
  66.     coin_count = 0;
  67.  
  68.     /* blank out the screen */
  69.     osd_clearbitmap(Machine->scrbitmap);
  70. }
  71.  
  72. void wardner_reset(void)
  73. {
  74.     /* clean out high score tables in these game hardware */
  75.     wardner_mainram[0x0117] = 0xff;
  76.     wardner_mainram[0x0118] = 0xff;
  77.     wardner_mainram[0x0119] = 0xff;
  78.     wardner_mainram[0x011a] = 0xff;
  79.     wardner_mainram[0x011b] = 0xff;
  80.     wardner_mainram[0x0170] = 0xff;
  81.     wardner_mainram[0x0171] = 0xff;
  82.     wardner_mainram[0x0172] = 0xff;
  83.  
  84.     toaplan_main_cpu = 1;        /* Z80 */
  85.     twincobr_intenable = 0;
  86.     twincobr_display_on = 1;
  87.     dsp_addr_w = dsp_execute = 0;
  88.     main_ram_seg = 0;
  89.  
  90.     /* coin count increments on startup ? , so stop it */
  91.     coin_count = 0;
  92.  
  93.     /* blank out the screen */
  94.     osd_clearbitmap(Machine->scrbitmap);
  95. }
  96.  
  97.  
  98. READ_HANDLER( twincobr_dsp_r )
  99. {
  100.     /* DSP can read data from main CPU RAM via DSP IO port 1 */
  101.  
  102.     unsigned int input_data = 0;
  103.     switch (main_ram_seg) {
  104.         case 0x30000:    input_data = READ_WORD(&twincobr_68k_dsp_ram[dsp_addr_w]); break;
  105.         case 0x40000:    input_data = READ_WORD(&spriteram[dsp_addr_w]); break;
  106.         case 0x50000:    input_data = READ_WORD(&paletteram[dsp_addr_w]); break;
  107.         case 0x7000:    input_data = wardner_mainram[dsp_addr_w] + (wardner_mainram[dsp_addr_w+1]<<8); break;
  108.         case 0x8000:    input_data = spriteram[dsp_addr_w] + (spriteram[dsp_addr_w+1]<<8); break;
  109.         case 0xa000:    input_data = paletteram[dsp_addr_w] + (paletteram[dsp_addr_w+1]<<8); break;
  110.         default:        logerror("DSP PC:%04x Warning !!! IO reading from %08x (port 1)\n",cpu_getpreviouspc(),main_ram_seg + dsp_addr_w);
  111.     }
  112. #if LOG_DSP_CALLS
  113.     logerror("DSP PC:%04x IO read %04x at %08x (port 1)\n",cpu_getpreviouspc(),input_data,main_ram_seg + dsp_addr_w);
  114. #endif
  115.     return input_data;
  116. }
  117.  
  118. READ_HANDLER( fsharkbt_dsp_r )
  119. {
  120.     /* Flying Shark bootleg uses IO port 2 */
  121.     /* DSP reads data from an extra MCU (8741) at IO port 2 */
  122.     /* Boot-leggers using their own copy protection ?? */
  123.     /* Port is read three times during startup. First and last data */
  124.     /*     read must equal, but second read data must be different */
  125.     fsharkbt_8741 += 1;
  126. #if LOG_DSP_CALLS
  127.     logerror("DSP PC:%04x IO read %04x from 8741 MCU (port 2)\n",cpu_getpreviouspc(),(fsharkbt_8741 & 0x08));
  128. #endif
  129.     return (fsharkbt_8741 & 1);
  130. }
  131.  
  132. WRITE_HANDLER( twincobr_dsp_w )
  133. {
  134.     if (offset == 0) {
  135.         /* This sets the main CPU RAM address the DSP should */
  136.         /*        read/write, via the DSP IO port 0 */
  137.         /* Top three bits of data need to be shifted left 3 places */
  138.         /*        to select which memory bank from main CPU address */
  139.         /*        space to use */
  140.         /* Lower thirteen bits of this data is shifted left one position */
  141.         /*        to move it to an even address word boundary */
  142.  
  143.         dsp_addr_w = ((data & 0x1fff) << 1);
  144.         main_ram_seg = ((data & 0xe000) << 3);
  145.         if (toaplan_main_cpu == 1) {        /* Z80 */
  146.             dsp_addr_w &= 0xfff;
  147.             if (main_ram_seg == 0x30000) main_ram_seg = 0x7000;
  148.             if (main_ram_seg == 0x40000) main_ram_seg = 0x8000;
  149.             if (main_ram_seg == 0x50000) main_ram_seg = 0xa000;
  150.         }
  151. #if LOG_DSP_CALLS
  152.         logerror("DSP PC:%04x IO write %04x (%08x) at port 0\n",cpu_getpreviouspc(),data,main_ram_seg + dsp_addr_w);
  153. #endif
  154.     }
  155.     if (offset == 1) {
  156.         /* Data written to main CPU RAM via DSP IO port 1*/
  157.         dsp_execute = 0;
  158.         switch (main_ram_seg) {
  159.             case 0x30000:    WRITE_WORD(&twincobr_68k_dsp_ram[dsp_addr_w],data);
  160.                                 if ((dsp_addr_w < 3) && (data == 0)) dsp_execute = 1; break;
  161.             case 0x40000:    WRITE_WORD(&spriteram[dsp_addr_w],data); break;
  162.             case 0x50000:    WRITE_WORD(&paletteram[dsp_addr_w],data); break;
  163.             case 0x7000:    wardner_mainram[dsp_addr_w] = data & 0xff;
  164.                             wardner_mainram[dsp_addr_w + 1] = (data >> 8) & 0xff;
  165.                             if ((dsp_addr_w < 3) && (data == 0)) dsp_execute = 1; break;
  166.             case 0x8000:    spriteram[dsp_addr_w] = data & 0xff;
  167.                             spriteram[dsp_addr_w + 1] = (data >> 8) & 0xff;break;
  168.             case 0xa000:    paletteram[dsp_addr_w] = data & 0xff;
  169.                             paletteram[dsp_addr_w + 1] = (data >> 8) & 0xff; break;
  170.             default:        logerror("DSP PC:%04x Warning !!! IO writing to %08x (port 1)\n",cpu_getpreviouspc(),main_ram_seg + dsp_addr_w);
  171.         }
  172. #if LOG_DSP_CALLS
  173.         logerror("DSP PC:%04x IO write %04x at %08x (port 1)\n",cpu_getpreviouspc(),data,main_ram_seg + dsp_addr_w);
  174. #endif
  175.     }
  176.     if (offset == 2) {
  177.         /* Flying Shark bootleg DSP writes data to an extra MCU (8741) at IO port 2 */
  178. #if 0
  179.         logerror("DSP PC:%04x IO write from DSP RAM:%04x to 8741 MCU (port 2)\n",cpu_getpreviouspc(),fsharkbt_8741);
  180. #endif
  181.     }
  182.     if (offset == 3) {
  183.         /* data 0xffff    means inhibit BIO line to DSP and enable  */
  184.         /*                communication to main processor */
  185.         /*                Actually only DSP data bit 15 controls this */
  186.         /* data 0x0000    means set DSP BIO line active and disable */
  187.         /*                communication to main processor*/
  188. #if LOG_DSP_CALLS
  189.         logerror("DSP PC:%04x IO write %04x at port 3\n",cpu_getpreviouspc(),data);
  190. #endif
  191.         if (data & 0x8000) {
  192.             cpu_set_irq_line(2, TMS320C10_ACTIVE_BIO, CLEAR_LINE);
  193.         }
  194.         if (data == 0) {
  195.             if (dsp_execute) {
  196. #if LOG_DSP_CALLS
  197.                 logerror("Turning %s on\n",toaplan_cpu_type[toaplan_main_cpu]);
  198. #endif
  199.                 timer_suspendcpu(0, CLEAR, SUSPEND_REASON_HALT);
  200.                 dsp_execute = 0;
  201.             }
  202.             cpu_set_irq_line(2, TMS320C10_ACTIVE_BIO, ASSERT_LINE);
  203.         }
  204.     }
  205. }
  206.  
  207. READ_HANDLER( twincobr_68k_dsp_r )
  208. {
  209.     return READ_WORD(&twincobr_68k_dsp_ram[offset]);
  210. }
  211.  
  212. WRITE_HANDLER( twincobr_68k_dsp_w )
  213. {
  214. #if LOG_DSP_CALLS
  215.     if (offset < 10) logerror("%s:%08x write %08x at %08x\n",toaplan_cpu_type[toaplan_main_cpu],cpu_get_pc(),data,0x30000+offset);
  216. #endif
  217.     COMBINE_WORD_MEM(&twincobr_68k_dsp_ram[offset],data);
  218. }
  219.  
  220.  
  221. WRITE_HANDLER( wardner_mainram_w )
  222. {
  223. #if 0
  224.     if ((offset == 4) && (data != 4)) logerror("CPU #0:%04x  Writing %02x to %04x of main RAM (DSP command number)\n",cpu_get_pc(),data, offset + 0x7000);
  225. #endif
  226.     wardner_mainram[offset] = data;
  227.  
  228. }
  229. READ_HANDLER( wardner_mainram_r )
  230. {
  231.     return wardner_mainram[offset];
  232. }
  233.  
  234.  
  235. WRITE_HANDLER( twincobr_7800c_w )
  236. {
  237. #if 0
  238.     logerror("%s:%08x  Writing %08x to %08x.\n",toaplan_cpu_type[toaplan_main_cpu],cpu_get_pc(),data,toaplan_port_type[toaplan_main_cpu] - offset);
  239. #endif
  240.  
  241.     if (toaplan_main_cpu == 1) {
  242.         if (data == 0x0c) { data = 0x1c; wardner_sprite_hack=0; }    /* Z80 ? */
  243.         if (data == 0x0d) { data = 0x1d; wardner_sprite_hack=1; }    /* Z80 ? */
  244.     }
  245.  
  246.     switch (data) {
  247.         case 0x0004: twincobr_intenable = 0; break;
  248.         case 0x0005: twincobr_intenable = 1; break;
  249.         case 0x0006: twincobr_flip_screen = 0; twincobr_flip_x_base=0x037; twincobr_flip_y_base=0x01e; break;
  250.         case 0x0007: twincobr_flip_screen = 1; twincobr_flip_x_base=0x085; twincobr_flip_y_base=0x0f2; break;
  251.         case 0x0008: twincobr_bg_ram_bank = 0x0000; break;
  252.         case 0x0009: twincobr_bg_ram_bank = 0x2000; break;
  253.         case 0x000a: twincobr_fg_rom_bank = 0x0000; break;
  254.         case 0x000b: twincobr_fg_rom_bank = 0x1000; break;
  255.         case 0x000e: twincobr_display_on  = 0x0000; break; /* Turn display off */
  256.         case 0x000f: twincobr_display_on  = 0x0001; break; /* Turn display on */
  257.         case 0x000c: if (twincobr_display_on) {
  258.                         /* This means assert the INT line to the DSP */
  259. #if LOG_DSP_CALLS
  260.                         logerror("Turning DSP on and %s off\n",toaplan_cpu_type[toaplan_main_cpu]);
  261. #endif
  262.                         timer_suspendcpu(2, CLEAR, SUSPEND_REASON_HALT);
  263.                         cpu_set_irq_line(2, TMS320C10_ACTIVE_INT, ASSERT_LINE);
  264.                         timer_suspendcpu(0, ASSERT, SUSPEND_REASON_HALT);
  265.                     } break;
  266.         case 0x000d: if (twincobr_display_on) {
  267.                         /* This means inhibit the INT line to the DSP */
  268. #if LOG_DSP_CALLS
  269.                         logerror("Turning DSP off\n");
  270. #endif
  271.                         cpu_set_irq_line(2, TMS320C10_ACTIVE_INT, CLEAR_LINE);
  272.                         timer_suspendcpu(2, ASSERT, SUSPEND_REASON_HALT);
  273.                     } break;
  274.     }
  275. }
  276.  
  277.  
  278.  
  279. READ_HANDLER( twincobr_sharedram_r )
  280. {
  281.     return twincobr_sharedram[offset / 2];
  282. }
  283.  
  284. WRITE_HANDLER( twincobr_sharedram_w )
  285. {
  286.     twincobr_sharedram[offset / 2] = data;
  287. }
  288.  
  289. WRITE_HANDLER( fshark_coin_dsp_w )
  290. {
  291. #if 0
  292.     if (data > 1)
  293.         logerror("%s:%08x  Writing %08x to %08x.\n",toaplan_cpu_type[toaplan_main_cpu],cpu_get_pc(),data,toaplan_port_type[toaplan_main_cpu] - offset);
  294. #endif
  295.     switch (data) {
  296.         case 0x08: if (coin_count) { coin_counter_w(0,1); coin_counter_w(0,0); } break;
  297.         case 0x09: if (coin_count) { coin_counter_w(2,1); coin_counter_w(2,0); } break;
  298.         case 0x0a: if (coin_count) { coin_counter_w(1,1); coin_counter_w(1,0); } break;
  299.         case 0x0b: if (coin_count) { coin_counter_w(3,1); coin_counter_w(3,0); } break;
  300.         case 0x0c: coin_lockout_w(0,1); coin_lockout_w(2,1); break;
  301.         case 0x0d: coin_lockout_w(0,0); coin_lockout_w(2,0); break;
  302.         case 0x0e: coin_lockout_w(1,1); coin_lockout_w(3,1); break;
  303.         case 0x0f: coin_lockout_w(1,0); coin_lockout_w(3,0); coin_count=1; break;
  304.         case 0x00:    /* This means assert the INT line to the DSP */
  305. #if LOG_DSP_CALLS
  306.                     logerror("Turning DSP on and %s off\n",toaplan_cpu_type[toaplan_main_cpu]);
  307. #endif
  308.                     timer_suspendcpu(2, CLEAR, SUSPEND_REASON_HALT);
  309.                     cpu_set_irq_line(2, TMS320C10_ACTIVE_INT, ASSERT_LINE);
  310.                     timer_suspendcpu(0, ASSERT, SUSPEND_REASON_HALT);
  311.                     break;
  312.         case 0x01:    /* This means inhibit the INT line to the DSP */
  313. #if LOG_DSP_CALLS
  314.                     logerror("Turning DSP off\n");
  315. #endif
  316.                     cpu_set_irq_line(2, TMS320C10_ACTIVE_INT, CLEAR_LINE);
  317.                     timer_suspendcpu(2, ASSERT, SUSPEND_REASON_HALT);
  318.                     break;
  319.     }
  320. }
  321.